#include "cons.h"

void * eval(struct cons * c) {
  if(consp(c)) {
    assert (funcp(c->car));
    return (struct cons *(*)(struct cons *))(*cons->car)(cons);
  } else {
    assert(datap(c));
    return c->cdr;
  }
}

/**
   Expected input:  (cons tree turned 45 degrees counter clockwise.)

     c = cons
     f = function 
     d = data

   c-c-     c-c-d
   | |  ... | |
   f f      f f

   Output:  Each of the functions (f's in the tree) are applied to the output 
   of the f below (to the right of) it.  The bottom (right-most) f is applied 
   to the value of d.

*/

void * filter(struct cons * c) {
  void * data;
  assert(consp(c));
  assert(funcp(c->car) && (&filter == c->car));
  assert(consp(c->cdr));
  
  if(datap(c->cdr)) {
    data = c->cdr->cdr;
  } else if(consp(c->cdr)) {
    data = filter(c->cdr);
  } else {
    assert (0);
  }
  return ((void*(*)(void*))*(c->car->car))(data);
}
